home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / msdos / raytrace / pov / bin / xtras / addon0.c < prev    next >
C/C++ Source or Header  |  1994-09-11  |  36KB  |  1,548 lines

  1. /****************************************************************************
  2. *
  3. *  ATTENTION!!!
  4. *
  5. *  THIS FILE HAS BEEN MODIFIED!!! IT IS NOT PART OF THE OFFICAL
  6. *  POV-RAY 2.2 DISTRIBUTION!!!
  7. *
  8. *  THIS FILE IS PART OF "FASTER THAN POV-RAY" (VERSION 2.2),
  9. *  A SPED-UP VERSION OF POV-RAY 2.2. USE AT YOUR OWN RISK!!!!!!
  10. *
  11. *  New files: addon0.c, addon1.c, addon2.c, addon3.c, addon.h
  12. *
  13. *  The additional modules were written by Dieter Bayer.
  14. *
  15. *  Send comments, suggestions, bugs, ideas ... to:
  16. *
  17. *  e-mail: dieter@cip.e-technik.uni-erlangen.de
  18. *  CIS: 100255.3074
  19. *
  20. *  All changed/added lines are enclosed in #ifdef DB_CODE ... #endif
  21. *
  22. *  The vista projection was taken from:
  23. *
  24. *    A. Hashimoto, T. Akimoto, K. Mase, and Y. Suenaga, 
  25. *    "Vista Ray-Tracing: High Speed Ray Tracing Using Perspective
  26. *    Projection Image", New Advances in Computer Graphics, Proceedings
  27. *    of CG International '89, R. A. Earnshaw, B. Wyvill (Eds.), 
  28. *    Springer, ..., pp. 549-560
  29. *
  30. *  The idea for the light buffer was taken from:
  31. *
  32. *    E. Haines and D. Greenberg, "The Light Buffer: A Shadow-Testing 
  33. *    Accelerator", IEEE CG&A, Vol. 6, No. 9, Sept. 1986, pp. 6-16
  34. *
  35. *****************************************************************************/
  36.  
  37. /*****************************************************************************
  38. *  addon0.c
  39. *
  40. *  This module was written by Dieter Bayer.
  41. *
  42. *  This module contains functions for initialisation, statistics, previewing,
  43. *  and other gegeneral purposes.
  44. *
  45. *  01.03.1994 : Creation
  46. *
  47. *  29.04.1994 : Version 2.0
  48. *
  49. ******************************************************************************/
  50.  
  51. #include <time.h>
  52. #include "frame.h"
  53. #include "vector.h"
  54. #include "povproto.h"
  55. #include "addon.h"
  56.  
  57. #ifdef DB_CODE
  58.  
  59. #define RED 0
  60. #define GREEN 1
  61. #define BLUE 2
  62.  
  63. #define NUMBER_OF_TYPES      19
  64. #define TYPE_BICUBIC_PATCH    0
  65. #define TYPE_BLOB             1
  66. #define TYPE_BOX              2
  67. #define TYPE_CONE             3
  68. #define TYPE_CSG_INTERSECTION 4
  69. #define TYPE_CSG_MERGE        5
  70. #define TYPE_CSG_UNION        6
  71. #define TYPE_DISC             7
  72. #define TYPE_ELLIPSOID        8
  73. #define TYPE_HEIGHT_FIELD     9
  74. #define TYPE_LIGHT_SOURCE    10
  75. #define TYPE_PLANE           11
  76. #define TYPE_POLY            12
  77. #define TYPE_POLYGON         13
  78. #define TYPE_QUADRIC         14
  79. #define TYPE_SMOOTH_TRIANGLE 15
  80. #define TYPE_SPHERE          16
  81. #define TYPE_TRIANGLE        17
  82. #define TYPE_UNKNOWN         18
  83.  
  84. #define NUMBER_OF_FLAGS     7
  85. #define FLAG_SUM            0
  86. #define FLAG_INFINITE       1
  87. #define FLAG_USED_IN_CSG    2
  88. #define FLAG_BOUNDED        3
  89. #define FLAG_CLIPPED        4
  90. #define FLAG_BOUND_OBJECT   5
  91. #define FLAG_CLIP_OBJECT    6
  92.  
  93.  
  94.  
  95. /*****************************************************************************
  96. * External variables
  97. ******************************************************************************/
  98.  
  99. extern FRAME Frame;
  100. extern unsigned int Options;
  101. extern METHODS Ellipsoid_Methods;
  102. extern METHODS Sphere_Methods;
  103. extern time_t tstart, tstop;
  104. extern int Use_Slabs;
  105. extern unsigned long Quality_Flags;
  106.  
  107. extern METHODS Bicubic_Patch_Methods;
  108. extern METHODS Blob_Methods;
  109. extern METHODS Box_Methods;
  110. extern METHODS Cone_Methods;
  111. extern METHODS Csg_Height_Field_Methods;
  112. extern METHODS CSG_Intersection_Methods;
  113. extern METHODS CSG_Merge_Methods;
  114. extern METHODS CSG_Union_Methods;
  115. extern METHODS Disc_Methods;
  116. extern METHODS Ellipsoid_Methods;
  117. extern METHODS Height_Field_Methods;
  118. extern METHODS Light_Source_Methods;
  119. extern METHODS Plane_Methods;
  120. extern METHODS Poly_Methods;
  121. extern METHODS Quadric_Methods;
  122. extern METHODS Smooth_Triangle_Methods;
  123. extern METHODS Sphere_Methods;
  124. extern METHODS Triangle_Methods;
  125.  
  126. extern PROJECT_TREE_NODE *Root_Vista;
  127.  
  128. extern size_t Mem_Polygon;
  129.  
  130.  
  131.  
  132. /*****************************************************************************
  133. * Global variables
  134. ******************************************************************************/
  135.  
  136. unsigned int Extended_Options = 0;
  137.  
  138. /* Amount of memory occupied by the vista buffer and light buffers */
  139.  
  140. size_t Mem_Vista_Buffer  = 0;
  141. size_t Mem_Light_Buffers = 0;
  142. size_t Allocated_Memory  = 0;
  143.  
  144.  
  145.  
  146. /*****************************************************************************
  147. * Static variables
  148. ******************************************************************************/
  149.  
  150. static int Point_Counter;
  151.  
  152. static DBL time_used1, time_used2;
  153.  
  154. static long counter[NUMBER_OF_TYPES][NUMBER_OF_FLAGS];
  155.  
  156.  
  157.  
  158. /*****************************************************************************
  159. * Static functions
  160. ******************************************************************************/
  161.  
  162. static int Get_Object_Type PARAMS((OBJECT *Object));
  163. static void Print_Object_Info PARAMS((int type));
  164. static void Get_Object_Stats PARAMS((OBJECT *Object, int Csg, int Bound_Object, int Clip_Object));
  165. static void Print_Object_Stats PARAMS((void));
  166.  
  167. static void Draw_Projection PARAMS((PROJECT *Project, int color));
  168. static void Draw_Vista PARAMS((PROJECT_TREE_NODE *Tree));
  169.  
  170.  
  171.  
  172. /*****************************************************************************
  173. *
  174. * FUNCTION      : VB_malloc
  175. *
  176. * ARGUMENTS     : size   - Amount of memory to allocate
  177. *
  178. * MODIFIED ARGS : none
  179. *
  180. * RETURN VALUE  : void * - Pointer at allocated memory
  181. *
  182. * AUTHOR        : Dieter Bayer, May, 1994
  183. *
  184. * DESCRIPTION
  185. *
  186. *   Allocate memory for the vista buffer and keep track of the memory allocated.
  187. *
  188. * CHANGES
  189. *
  190. *   -
  191. *
  192. ******************************************************************************/
  193.  
  194. void *VB_malloc(size)
  195. size_t size;
  196. {
  197.   Allocated_Memory += size;
  198.  
  199.   Mem_Vista_Buffer += size;
  200.  
  201.   return(malloc(size));
  202. }
  203.  
  204.  
  205.  
  206. /*****************************************************************************
  207. *
  208. * FUNCTION      : LB_malloc
  209. *
  210. * ARGUMENTS     : size   - Amount of memory to allocate
  211. *
  212. * MODIFIED ARGS : none
  213. *
  214. * RETURN VALUE  : void * - Pointer at allocated memory
  215. *
  216. * AUTHOR        : Dieter Bayer, May, 1994
  217. *
  218. * DESCRIPTION
  219. *
  220. *   Allocate memory for the light buffer and keep track of the memory allocated.
  221. *
  222. * CHANGES
  223. *
  224. *   -
  225. *
  226. ******************************************************************************/
  227.  
  228. void *LB_malloc(size)
  229. size_t size;
  230. {
  231.   Allocated_Memory += size;
  232.  
  233.   Mem_Light_Buffers += size;
  234.  
  235.   return(malloc(size));
  236. }
  237.  
  238.  
  239.  
  240. /*****************************************************************************
  241. *
  242. * FUNCTION      : new_malloc
  243. *
  244. * ARGUMENTS     : size   - Amount of memory to allocate
  245. *
  246. * MODIFIED ARGS : none
  247. *
  248. * RETURN VALUE  : void * - Pointer at allocated memory
  249. *
  250. * AUTHOR        : Dieter Bayer, May, 1994
  251. *
  252. * DESCRIPTION
  253. *
  254. *   Allocate memory and keep track of the memory allocated.
  255. *
  256. *   Use instead of malloc when allocating memory!
  257. *
  258. * CHANGES
  259. *
  260. *   -
  261. *
  262. ******************************************************************************/
  263.  
  264. void *new_malloc(size)
  265. size_t size;
  266. {
  267.   Allocated_Memory += size;
  268.  
  269.   return(malloc(size));
  270. }
  271.  
  272.  
  273.  
  274. /*****************************************************************************
  275. *
  276. * FUNCTION      : new_free
  277. *
  278. * ARGUMENTS     : pointer - Memory to free
  279. *                 size    - Amount of memory that will be freed
  280. *
  281. * MODIFIED ARGS : none
  282. *
  283. * RETURN VALUE  : none
  284. *
  285. * AUTHOR        : Dieter Bayer, May, 1994
  286. *
  287. * DESCRIPTION
  288. *
  289. *   Free memory and keep track of the memory allocated.
  290. *
  291. *   Use instead of free when freeing memory!
  292. *
  293. * CHANGES
  294. *
  295. *   -
  296. *
  297. ******************************************************************************/
  298.  
  299. void new_free(pointer, size)
  300. void *pointer;
  301. size_t size;
  302. {
  303.   Allocated_Memory -= size;
  304.  
  305.   free(pointer);
  306. }
  307.  
  308.  
  309. /*****************************************************************************
  310. *
  311. * FUNCTION      : Init_Additional_1
  312. *
  313. * ARGUMENTS     : none
  314. *
  315. * MODIFIED ARGS : none
  316. *
  317. * RETURN VALUE  : none
  318. *
  319. * AUTHOR        : Dieter Bayer, May, 1994
  320. *
  321. * DESCRIPTION
  322. *
  323. *   Additional initialisation before boundind slabs are build.
  324. *
  325. *   Split union objects and pass bounding objects to the children if they
  326. *   aren't already bounded (most bounding objects will be removed later).
  327. *
  328. * CHANGES
  329. *
  330. *   -
  331. *
  332. ******************************************************************************/
  333.  
  334. void Init_Additionals_1()
  335. {
  336.   int children_finite;
  337.   long count;
  338.   DBL Volume;
  339.   OBJECT **Object, *Sib, *Last_Sib, *Bound;
  340.  
  341.   Print_Quadric_Stats();
  342.  
  343.   if ((Extended_Options & USE_SPLIT_FINITE_UNIONS) ||
  344.       (Extended_Options & USE_SPLIT_INFINITE_UNIONS))
  345.   {
  346.     START_TIME
  347.  
  348.     Recompute_Bboxes();
  349.  
  350.     fprintf(stderr, "Splitting union objects");
  351.  
  352.     Begin_Point();
  353.  
  354.     count = 0;
  355.  
  356.     for (Object = &Frame.Objects; (*Object) != NULL; )
  357.     {
  358.       children_finite = FALSE;
  359.  
  360.       if (Extended_Options & USE_SPLIT_INFINITE_UNIONS)
  361.       {
  362.     /* +usi option is used, i.e. split all unions */
  363.  
  364.     children_finite = TRUE;
  365.       }
  366.       else
  367.       {
  368.     /* Check, if all children of the union have finite bounding boxes */
  369.  
  370.     if ((*Object)->Methods == &CSG_Union_Methods)
  371.     {
  372.       children_finite = TRUE;
  373.  
  374.       for (Sib = ((CSG *)(*Object))->Children; Sib != NULL; Sib = Sib->Sibling)
  375.       {
  376.         BOUNDS_VOLUME(Volume, Sib->Bounds);
  377.         if (Volume > INFINITE_VOLUME) children_finite = FALSE;
  378.       }
  379.     }
  380.       }
  381.  
  382.       /* Split union object, if all children are finite (or tracing slows
  383.      down!) and the union isn't clipped */
  384.  
  385.       if (((*Object)->Methods == &CSG_Union_Methods) &&
  386.       ((*Object)->Clip == NULL) && (children_finite))
  387.       {
  388.     count++;
  389.  
  390.     Print_Point(POINT_MOD);
  391.  
  392.     Bound = (*Object)->Bound;
  393.  
  394.     if ((Sib = ((CSG *)(*Object))->Children) != NULL)
  395.     {
  396.       for (; Sib != NULL; Sib = Sib->Sibling)
  397.       {
  398.         /* Set child's bound to father's bound (some peolpe use objects
  399.            that don't fit in the bounding object. Argh!!!
  400.            The question is: should this be done or not?) */
  401.  
  402.         if (Sib->Bound == NULL) Sib->Bound = Bound;
  403.  
  404.         Last_Sib = Sib;
  405.       }
  406.  
  407.       Last_Sib->Sibling = (*Object)->Sibling;
  408.  
  409.       (*Object) = ((CSG *)(*Object))->Children;
  410.     }
  411.     else
  412.     {
  413.       (*Object) = (*Object)->Sibling;
  414.     }
  415.       }
  416.       else
  417.       {
  418.     Object = &(*Object)->Sibling;
  419.       }
  420.     }
  421.  
  422.     fprintf(stderr, "(%ld split)", count);
  423.  
  424.     End_Point();
  425.  
  426.     if (count > 0)
  427.     {
  428.       /* Just to be sure */
  429.  
  430.       Recompute_Bboxes();
  431.     }
  432.  
  433.     STOP_TIME
  434.  
  435.     time_used1 = TIME_ELAPSED
  436.   }
  437.   else
  438.   {
  439.     Recompute_Bboxes();
  440.   }
  441. }
  442.  
  443.  
  444.  
  445. /*****************************************************************************
  446. *
  447. * FUNCTION      : Init_Additionals_2
  448. *
  449. * ARGUMENTS     : none
  450. *
  451. * MODIFIED ARGS : none
  452. *
  453. * RETURN VALUE  : none
  454. *
  455. * AUTHOR        : Dieter Bayer, May, 1994
  456. *
  457. * DESCRIPTION
  458. *
  459. *   Additional initialisation after boundind slabs have been build.
  460. *
  461. *   - Project objects onto the screen.
  462. *   - Build the light buffers.
  463. *   - Remove all unnecessary bounding objects.
  464. *   - Print a statistic of the scene.
  465. *
  466. * CHANGES
  467. *
  468. *   -
  469. *
  470. ******************************************************************************/
  471.  
  472. void Init_Additionals_2()
  473. {
  474.   DBL time_used;
  475.  
  476.   /* If slabs are not used --> vista and light buffer can't be used */
  477.  
  478.   if (!Use_Slabs)
  479.   {
  480.     Extended_Options &= ~USE_VISTA_BUFFER;
  481.     Extended_Options &= ~USE_LIGHT_BUFFER;
  482.   }
  483.  
  484.   /* We don't use shadows so we don't need a light buffer */
  485.  
  486.   if (!(Quality_Flags & Q_SHADOW))
  487.   {
  488.     Extended_Options &= ~USE_LIGHT_BUFFER;
  489.   }
  490.  
  491.   if ((Extended_Options & USE_VISTA_BUFFER) ||
  492.       (Extended_Options & USE_LIGHT_BUFFER))
  493.   {
  494.     START_TIME
  495.  
  496.     if (Use_Slabs)
  497.     {
  498.       Init_Project_Tree_Queues();
  499.  
  500.       if (Extended_Options & USE_VISTA_BUFFER)
  501.       {
  502.     Init_View_Coordinates();
  503.  
  504.     Build_Vista_Tree();
  505.       }
  506.  
  507.       if (Extended_Options & USE_LIGHT_BUFFER)
  508.       {
  509.     Build_Light_Buffers();
  510.       }
  511.     }
  512.  
  513.     Remove_Unnecessary_Bounds();
  514.  
  515.     Print_Object_Stats();
  516.  
  517.     STOP_TIME
  518.  
  519.     time_used2 = TIME_ELAPSED
  520.  
  521.     time_used = time_used1 + time_used2;
  522.  
  523.     fprintf(stderr, "Preprocessing time: %.0f seconds\n", time_used);
  524.   }
  525.   else
  526.   {
  527.     Remove_Unnecessary_Bounds();
  528.   }
  529. }
  530.  
  531.  
  532.  
  533. /*****************************************************************************
  534. *
  535. * FUNCTION      : Get_Object_Type
  536. *
  537. * ARGUMENTS     : Object - Point to an object
  538. *
  539. * MODIFIED ARGS : none
  540. *
  541. * RETURN VALUE  : int - Type of object
  542. *
  543. * AUTHOR        : Dieter Bayer, May, 1994
  544. *
  545. * DESCRIPTION
  546. *
  547. *   Returns the type of an object.
  548. *
  549. * CHANGES
  550. *
  551. *   -
  552. *
  553. ******************************************************************************/
  554.  
  555. static int Get_Object_Type(Object)
  556. OBJECT *Object;
  557. {
  558.   if (Object->Methods == &Bicubic_Patch_Methods)    return(TYPE_BICUBIC_PATCH);
  559.  
  560.   if (Object->Methods == &Blob_Methods)             return(TYPE_BLOB);
  561.  
  562.   if (Object->Methods == &Box_Methods)              return(TYPE_BOX);
  563.  
  564.   if (Object->Methods == &Cone_Methods)             return(TYPE_CONE);
  565.  
  566.   if (Object->Methods == &CSG_Intersection_Methods) return(TYPE_CSG_INTERSECTION);
  567.  
  568.   if (Object->Methods == &CSG_Merge_Methods)        return(TYPE_CSG_MERGE);
  569.  
  570.   if (Object->Methods == &CSG_Union_Methods)        return(TYPE_CSG_UNION);
  571.  
  572.   if (Object->Methods == &Disc_Methods)             return(TYPE_DISC);
  573.  
  574.   if (Object->Methods == &Ellipsoid_Methods)        return(TYPE_ELLIPSOID);
  575.  
  576.   if (Object->Methods == &Height_Field_Methods)     return(TYPE_HEIGHT_FIELD);
  577.  
  578.   if (Object->Methods == &Csg_Height_Field_Methods) return(TYPE_HEIGHT_FIELD);
  579.  
  580.   if (Object->Methods == &Light_Source_Methods)     return(TYPE_LIGHT_SOURCE);
  581.  
  582.   if (Object->Methods == &Plane_Methods)            return(TYPE_PLANE);
  583.  
  584.   if (Object->Methods == &Poly_Methods)             return(TYPE_POLY);
  585.  
  586.   if (Object->Methods == &Quadric_Methods)          return(TYPE_QUADRIC);
  587.  
  588.   if (Object->Methods == &Smooth_Triangle_Methods)  return(TYPE_SMOOTH_TRIANGLE);
  589.  
  590.   if (Object->Methods == &Sphere_Methods)           return(TYPE_SPHERE);
  591.  
  592.   if (Object->Methods == &Triangle_Methods)         return(TYPE_TRIANGLE);
  593.  
  594.   return(TYPE_UNKNOWN);
  595. }
  596.  
  597.  
  598.  
  599. /*****************************************************************************
  600. *
  601. * FUNCTION      : Get_Object_Stats
  602. *
  603. * ARGUMENTS     : Object       - object
  604. *                 csg          - Flag if inside a csg object
  605. *                 bound_object - Flag if object is part of a bounding object
  606. *                 clip_object  - Flag if object is part of a clipping object
  607. *
  608. * MODIFIED ARGS : none
  609. *
  610. * RETURN VALUE  : none
  611. *
  612. * AUTHOR        : Dieter Bayer, May, 1994
  613. *
  614. * DESCRIPTION
  615. *
  616. *   Get some information about an object and add it to the scene statistic.
  617. *
  618. * CHANGES
  619. *
  620. *   -
  621. *
  622. ******************************************************************************/
  623.  
  624. static void Get_Object_Stats(Object, csg, bound_object, clip_object)
  625. OBJECT *Object;
  626. int csg, bound_object, clip_object;
  627. {
  628.   int bounded, clipped, infinite, type;
  629.   DBL Volume;
  630.  
  631.   OBJECT *Sib;
  632.  
  633.   if (Object == NULL)
  634.     return;
  635.  
  636.   /* Bounded/Clipped object? */
  637.  
  638.   bounded = (Object->Bound != NULL);
  639.   clipped = (Object->Clip != NULL);
  640.  
  641.   /* Don't care about infinite objects if they are inside
  642.      a CSG object or used as clipping/bounding objects */
  643.  
  644.   if (csg || bound_object || clip_object)
  645.   {
  646.     infinite = FALSE;
  647.   }
  648.   else
  649.   {
  650.     /* Infinte object? */
  651.  
  652.     BOUNDS_VOLUME(Volume, Object->Bounds);
  653.  
  654.     infinite = (Volume > INFINITE_VOLUME);
  655.   }
  656.  
  657.   /* Get object type */
  658.  
  659.   type = Get_Object_Type(Object);
  660.  
  661.   /* Count bounding objects */
  662.  
  663.   if (Object->Bound != NULL)
  664.   {
  665.     for (Sib = Object->Bound; Sib != NULL; Sib = Sib->Sibling)
  666.     {
  667.       Get_Object_Stats(Sib, csg, TRUE, clip_object);
  668.     }
  669.   }
  670.  
  671.   /* Count clipping objects */
  672.  
  673.   if (Object->Clip != NULL)
  674.   {
  675.     for (Sib = Object->Clip; Sib != NULL; Sib = Sib->Sibling)
  676.     {
  677.       Get_Object_Stats(Sib, csg, bound_object, TRUE);
  678.     }
  679.   }
  680.  
  681.   if (Object->Type & COMPOUND_OBJECT)
  682.   {
  683.     if (Object->Type & LIGHT_SOURCE_OBJECT)
  684.     {
  685.       /* Count light source */
  686.  
  687.       counter[type][FLAG_SUM]++;
  688.  
  689.       Get_Object_Stats(((LIGHT_SOURCE *)Object)->Children, csg, bound_object, clip_object);
  690.     }
  691.     else
  692.     {
  693.       /* Count CSG object */
  694.  
  695.       counter[type][FLAG_SUM]++;
  696.  
  697.       if (csg)            counter[type][FLAG_USED_IN_CSG]++;
  698.       if (infinite)       counter[type][FLAG_INFINITE]++;
  699.       if (bounded)        counter[type][FLAG_BOUNDED]++;
  700.       if (clipped)        counter[type][FLAG_CLIPPED]++;
  701.       if (bound_object)   counter[type][FLAG_BOUND_OBJECT]++;
  702.       if (clip_object)    counter[type][FLAG_CLIP_OBJECT]++;
  703.  
  704.       for (Sib = ((CSG *)Object)->Children; Sib != NULL; Sib = Sib->Sibling)
  705.       {
  706.     Get_Object_Stats(Sib, TRUE, bound_object, clip_object);
  707.       }
  708.     }
  709.   }
  710.   else
  711.   {
  712.     /* Count the primitive object */
  713.  
  714.     counter[type][FLAG_SUM]++;
  715.  
  716.     if (csg)            counter[type][FLAG_USED_IN_CSG]++;
  717.     if (infinite)       counter[type][FLAG_INFINITE]++;
  718.     if (bounded)        counter[type][FLAG_BOUNDED]++;
  719.     if (clipped)        counter[type][FLAG_CLIPPED]++;
  720.     if (bound_object)   counter[type][FLAG_BOUND_OBJECT]++;
  721.     if (clip_object)    counter[type][FLAG_CLIP_OBJECT]++;
  722.   }
  723. }
  724.  
  725.  
  726.  
  727. /*****************************************************************************
  728. *
  729. * FUNCTION      : Print_Object_Info
  730. *
  731. * ARGUMENTS     : type - Object's type
  732. *
  733. * MODIFIED ARGS : none
  734. *
  735. * RETURN VALUE  : none
  736. *
  737. * AUTHOR        : Dieter Bayer, May, 1994
  738. *
  739. * DESCRIPTION
  740. *
  741. *   Print the statistics of one type of object.
  742. *
  743. * CHANGES
  744. *
  745. *   -
  746. *
  747. ******************************************************************************/
  748.  
  749. static void Print_Object_Info(type)
  750. int type;
  751. {
  752.   fprintf(stderr, " : %5ld %5ld %5ld %5ld %5ld   %5ld   %5ld\n",
  753.     counter[type][FLAG_SUM],
  754.     counter[type][FLAG_USED_IN_CSG],
  755.     counter[type][FLAG_INFINITE],
  756.     counter[type][FLAG_BOUND_OBJECT],
  757.     counter[type][FLAG_CLIP_OBJECT],
  758.     counter[type][FLAG_BOUNDED],
  759.     counter[type][FLAG_CLIPPED]);
  760. }
  761.  
  762.  
  763.  
  764. /*****************************************************************************
  765. *
  766. * FUNCTION      : Print_Object_Stats
  767. *
  768. * ARGUMENTS     : none
  769. *
  770. * MODIFIED ARGS : none
  771. *
  772. * RETURN VALUE  : none
  773. *
  774. * AUTHOR        : Dieter Bayer, May, 1994
  775. *
  776. * DESCRIPTION
  777. *
  778. *   Collect and print a statistic about the scene.
  779. *
  780. * CHANGES
  781. *
  782. *   -
  783. *
  784. ******************************************************************************/
  785.  
  786. static void Print_Object_Stats()
  787. {
  788.   int i, j;
  789.   long sum1, sum2, sum3, sum4, sum5, sum6, sum7, frame_level;
  790.   OBJECT *Sib;
  791.  
  792.   /* Initialize counters */
  793.  
  794.   for (i = 0; i < NUMBER_OF_TYPES; i++)
  795.   {
  796.     for (j = 0; j < NUMBER_OF_FLAGS; j++)
  797.     {
  798.       counter[i][j] = 0;
  799.     }
  800.   }
  801.  
  802.   frame_level = 0;
  803.  
  804.   for (Sib = Frame.Objects; Sib != NULL; Sib = Sib->Sibling)
  805.   {
  806.     if (Sib->Type & LIGHT_SOURCE_OBJECT)
  807.     {
  808.       if (((LIGHT_SOURCE *)Sib)->Children != NULL)
  809.       {
  810.     frame_level++;
  811.       }
  812.     }
  813.     else
  814.     {
  815.       frame_level++;
  816.     }
  817.     Get_Object_Stats(Sib, FALSE, FALSE, FALSE);
  818.   }
  819.  
  820.   sum1 = sum2 = sum3 = sum4 = sum5 = sum6 = sum7 = 0;
  821.  
  822.   for (i = 0; i < NUMBER_OF_TYPES; i++)
  823.   {
  824.     sum1 += counter[i][FLAG_SUM];
  825.     sum2 += counter[i][FLAG_USED_IN_CSG];
  826.     sum3 += counter[i][FLAG_INFINITE];
  827.     sum4 += counter[i][FLAG_BOUND_OBJECT];
  828.     sum5 += counter[i][FLAG_CLIP_OBJECT];
  829.     sum6 += counter[i][FLAG_BOUNDED];
  830.     sum7 += counter[i][FLAG_CLIPPED];
  831.   }
  832.  
  833.   fprintf(stderr, "                     sum   csg infin bound  clip bounded clipped  KBytes\n");
  834.   fprintf(stderr, "Blob            "); Print_Object_Info(TYPE_BLOB);
  835.   fprintf(stderr, "Box             "); Print_Object_Info(TYPE_BOX);
  836.   fprintf(stderr, "Cone/Cylinder   "); Print_Object_Info(TYPE_CONE);
  837.   fprintf(stderr, "Ellipsoid       "); Print_Object_Info(TYPE_ELLIPSOID);
  838.   fprintf(stderr, "Height Field    "); Print_Object_Info(TYPE_HEIGHT_FIELD);
  839.   fprintf(stderr, "Sphere          "); Print_Object_Info(TYPE_SPHERE);
  840.  
  841.   fprintf(stderr, "Bicubic Patch   "); Print_Object_Info(TYPE_BICUBIC_PATCH);
  842.   fprintf(stderr, "Disc            "); Print_Object_Info(TYPE_DISC);
  843.   fprintf(stderr, "Smooth Triangle "); Print_Object_Info(TYPE_SMOOTH_TRIANGLE);
  844.   fprintf(stderr, "Triangle        "); Print_Object_Info(TYPE_TRIANGLE);
  845.  
  846.   fprintf(stderr, "Plane           "); Print_Object_Info(TYPE_PLANE);
  847.   fprintf(stderr, "Poly/Quartic    "); Print_Object_Info(TYPE_POLY);
  848.   fprintf(stderr, "Quadric         "); Print_Object_Info(TYPE_QUADRIC);
  849.  
  850.   fprintf(stderr, "CSG Intersection"); Print_Object_Info(TYPE_CSG_INTERSECTION);
  851.   fprintf(stderr, "CSG Merge       "); Print_Object_Info(TYPE_CSG_MERGE);
  852.   fprintf(stderr, "CSG Union       "); Print_Object_Info(TYPE_CSG_UNION);
  853.  
  854.   fprintf(stderr, "Light Source    "); Print_Object_Info(TYPE_LIGHT_SOURCE);
  855.  
  856.   fprintf(stderr, "TOTAL            : %5ld %5ld %5ld %5ld %5ld   %5ld   %5ld\n", sum1, sum2, sum3, sum4, sum5, sum6, sum7);
  857.  
  858.   fprintf(stderr, "Scene contains %ld frame level objects.\n", frame_level);
  859.  
  860.   /* Print amount of allocated memory */
  861.  
  862.   if (Mem_Vista_Buffer)
  863.     fprintf(stderr, "Vista Buffer : %.2f KBytes\n", (DBL)(Mem_Vista_Buffer) / 1024.0);
  864.  
  865.   if (Mem_Light_Buffers)
  866.     fprintf(stderr, "Light Buffer : %.2f KBytes\n", (DBL)(Mem_Light_Buffers) / 1024.0);
  867.  
  868.   if (Allocated_Memory)
  869.     fprintf(stderr, "Total        : %.2f KBytes\n", (DBL)Allocated_Memory / 1024.0);
  870. }
  871.  
  872.  
  873.  
  874. /*****************************************************************************
  875. *
  876. * FUNCTION      : Clip_Polygon
  877. *
  878. * ARGUMENTS     : Points             - polygon's points
  879. *                 PointCnt           - Number of points in polygon
  880. *                 VX1, VY1, VX2, VY1 - Normal vectors of the clipping planes
  881. *                 DX1, DY1, DX2, DY2 - Distances of the clipping planes from
  882. *                                      the origin
  883. *
  884. * MODIFIED ARGS : Points, PointCnt
  885. *
  886. * RETURN VALUE  : none
  887. *
  888. * AUTHOR        : Dieter Bayer, May, 1994
  889. *
  890. * DESCRIPTION
  891. *
  892. *   Clip polygon at the viewing pyramid define by the normal vectors
  893. *   VX1, VX2, VY1, VY2 and the distances DX1, DX2, DY1, DY2.
  894. *
  895. * CHANGES
  896. *
  897. *   -
  898. *
  899. ******************************************************************************/
  900.  
  901. void Clip_Polygon (Points, PointCnt, VX1, VX2, VY1, VY2, DX1, DX2, DY1, DY2)
  902. VECTOR *Points;
  903. int *PointCnt;
  904. VECTOR *VX1, *VX2, *VY1, *VY2;
  905. DBL DX1, DX2, DY1, DY2;
  906. {
  907.   DBL aktd, pred, fird, k;
  908.   VECTOR aktP, intP, preP, firP, d;
  909.   int i, pc;
  910.   VECTOR ClipPoints[MAX_CLIP_POINTS];
  911.  
  912.   /********** clip polygon at "left" plane **********/
  913.  
  914.   pc = 0;
  915.  
  916.   firP = Points[0];
  917.   fird = VX1->x * firP.x + VX1->y * firP.y + VX1->z * firP.z - DX1;
  918.  
  919.   if (fird <= 0.0)
  920.     ClipPoints[pc++] = firP;
  921.  
  922.   aktP = preP = firP;
  923.   aktd = pred = fird;
  924.  
  925.   for (i = 1; i < *PointCnt; i++)
  926.   {
  927.     aktP = Points[i];
  928.     aktd = VX1->x * aktP.x + VX1->y * aktP.y + VX1->z * aktP.z - DX1;
  929.  
  930.     if (((aktd < 0.0) && (pred > 0.0)) || ((aktd > 0.0) && (pred < 0.0)))
  931.     {
  932.       d.x = preP.x - aktP.x;
  933.       d.y = preP.y - aktP.y;
  934.       d.z = preP.z - aktP.z;
  935.  
  936.       k = -aktd / (VX1->x * d.x + VX1->y * d.y + VX1->z * d.z);
  937.  
  938.       intP.x = aktP.x + k * d.x;
  939.       intP.y = aktP.y + k * d.y;
  940.       intP.z = aktP.z + k * d.z;
  941.  
  942.       ClipPoints[pc++] = intP;
  943.     }
  944.  
  945.     if (aktd <= 0.0)
  946.       ClipPoints[pc++] = aktP;
  947.  
  948.     preP = aktP;
  949.     pred = aktd;
  950.   }
  951.  
  952.   if (((fird < 0.0) && (aktd > 0.0)) || ((fird > 0.0) && (aktd < 0.0)))
  953.   {
  954.     d.x = firP.x - aktP.x;
  955.     d.y = firP.y - aktP.y;
  956.     d.z = firP.z - aktP.z;
  957.  
  958.     k = -aktd / (VX1->x * d.x + VX1->y * d.y + VX1->z * d.z);
  959.  
  960.     intP.x = aktP.x + k * d.x;
  961.     intP.y = aktP.y + k * d.y;
  962.     intP.z = aktP.z + k * d.z;
  963.  
  964.     ClipPoints[pc++] = intP;
  965.   }
  966.  
  967.   for (i = 0; i < pc; i++)
  968.     Points[i] = ClipPoints[i];
  969.  
  970.   if ((*PointCnt = pc) == 0)
  971.     return;
  972.  
  973.   /********** clip polygon at "right" plane **********/
  974.  
  975.   pc = 0;
  976.  
  977.   firP = Points[0];
  978.   fird = VX2->x * firP.x + VX2->y * firP.y + VX2->z * firP.z - DX2;
  979.  
  980.   if (fird <= 0.0)
  981.     ClipPoints[pc++] = firP;
  982.  
  983.   aktP = preP = firP;
  984.   aktd = pred = fird;
  985.  
  986.   for (i = 1; i < *PointCnt; i++)
  987.   {
  988.     aktP = Points[i];
  989.     aktd = VX2->x * aktP.x + VX2->y * aktP.y + VX2->z * aktP.z - DX2;
  990.  
  991.     if (((aktd < 0.0) && (pred > 0.0)) || ((aktd > 0.0) && (pred < 0.0)))
  992.     {
  993.       d.x = preP.x - aktP.x;
  994.       d.y = preP.y - aktP.y;
  995.       d.z = preP.z - aktP.z;
  996.       
  997.       k = -aktd / (VX2->x * d.x + VX2->y * d.y + VX2->z * d.z);
  998.       
  999.       intP.x = aktP.x + k * d.x;
  1000.       intP.y = aktP.y + k * d.y;
  1001.       intP.z = aktP.z + k * d.z;
  1002.  
  1003.       ClipPoints[pc++] = intP;
  1004.     }
  1005.  
  1006.     if (aktd <= 0.0)
  1007.       ClipPoints[pc++] = aktP;
  1008.  
  1009.     preP = aktP;
  1010.     pred = aktd;
  1011.   }
  1012.  
  1013.   if (((fird < 0.0) && (aktd > 0.0)) || ((fird > 0.0) && (aktd < 0.0)))
  1014.   {
  1015.     d.x = firP.x - aktP.x;
  1016.     d.y = firP.y - aktP.y;
  1017.     d.z = firP.z - aktP.z;
  1018.  
  1019.     k = -aktd / (VX2->x * d.x + VX2->y * d.y + VX2->z * d.z);
  1020.  
  1021.     intP.x = aktP.x + k * d.x;
  1022.     intP.y = aktP.y + k * d.y;
  1023.     intP.z = aktP.z + k * d.z;
  1024.  
  1025.     ClipPoints[pc++] = intP;
  1026.   }
  1027.  
  1028.   for (i = 0; i < pc; i++)
  1029.     Points[i] = ClipPoints[i];
  1030.  
  1031.   if ((*PointCnt = pc) == 0)
  1032.     return;
  1033.  
  1034.   /********** clip polygon at "bottom" plane **********/
  1035.  
  1036.   pc = 0;
  1037.  
  1038.   firP = Points[0];
  1039.   fird = VY1->x * firP.x + VY1->y * firP.y + VY1->z * firP.z - DY1;
  1040.  
  1041.   if (fird <= 0.0)
  1042.     ClipPoints[pc++] = firP;
  1043.  
  1044.   aktP = preP = firP;
  1045.   aktd = pred = fird;
  1046.  
  1047.   for (i = 1; i < *PointCnt; i++)
  1048.   {
  1049.     aktP = Points[i];
  1050.     aktd = VY1->x * aktP.x + VY1->y * aktP.y + VY1->z * aktP.z - DY1;
  1051.  
  1052.     if (((aktd < 0.0) && (pred > 0.0)) || ((aktd > 0.0) && (pred < 0.0)))
  1053.     {
  1054.       d.x = preP.x - aktP.x;
  1055.       d.y = preP.y - aktP.y;
  1056.       d.z = preP.z - aktP.z;
  1057.       
  1058.       k = -aktd / (VY1->x * d.x + VY1->y * d.y + VY1->z * d.z);
  1059.       
  1060.       intP.x = aktP.x + k * d.x;
  1061.       intP.y = aktP.y + k * d.y;
  1062.       intP.z = aktP.z + k * d.z;
  1063.  
  1064.       ClipPoints[pc++] = intP;
  1065.     }
  1066.  
  1067.     if (aktd <= 0.0)
  1068.       ClipPoints[pc++] = aktP;
  1069.  
  1070.     preP = aktP;
  1071.     pred = aktd;
  1072.   }
  1073.  
  1074.   if (((fird < 0.0) && (aktd > 0.0)) || ((fird > 0.0) && (aktd < 0.0)))
  1075.   {
  1076.     d.x = firP.x - aktP.x;
  1077.     d.y = firP.y - aktP.y;
  1078.     d.z = firP.z - aktP.z;
  1079.  
  1080.     k = -aktd / (VY1->x * d.x + VY1->y * d.y + VY1->z * d.z);
  1081.  
  1082.     intP.x = aktP.x + k * d.x;
  1083.     intP.y = aktP.y + k * d.y;
  1084.     intP.z = aktP.z + k * d.z;
  1085.  
  1086.     ClipPoints[pc++] = intP;
  1087.   }
  1088.  
  1089.   for (i = 0; i < pc; i++)
  1090.     Points[i] = ClipPoints[i];
  1091.  
  1092.   if ((*PointCnt = pc) == 0)
  1093.     return;
  1094.  
  1095.   /********** clip polygon at "top" plane **********/
  1096.  
  1097.   pc = 0;
  1098.  
  1099.   firP = Points[0];
  1100.   fird = VY2->x * firP.x + VY2->y * firP.y + VY2->z * firP.z - DY2;
  1101.  
  1102.   if (fird <= 0.0)
  1103.     ClipPoints[pc++] = firP;
  1104.  
  1105.   aktP = preP = firP;
  1106.   aktd = pred = fird;
  1107.  
  1108.   for (i = pc = 0; i < *PointCnt; i++)
  1109.   {
  1110.     aktP = Points[i];
  1111.     aktd = VY2->x * aktP.x + VY2->y * aktP.y + VY2->z * aktP.z - DY2;
  1112.  
  1113.     if (((aktd < 0.0) && (pred > 0.0)) || ((aktd > 0.0) && (pred < 0.0)))
  1114.     {
  1115.       d.x = preP.x - aktP.x;
  1116.       d.y = preP.y - aktP.y;
  1117.       d.z = preP.z - aktP.z;
  1118.       
  1119.       k = -aktd / (VY2->x * d.x + VY2->y * d.y + VY2->z * d.z);
  1120.      
  1121.       intP.x = aktP.x + k * d.x;
  1122.       intP.y = aktP.y + k * d.y;
  1123.       intP.z = aktP.z + k * d.z;
  1124.       
  1125.       ClipPoints[pc++] = intP;
  1126.     }
  1127.  
  1128.     if (aktd <= 0.0)
  1129.       ClipPoints[pc++] = aktP;
  1130.  
  1131.     preP = aktP;
  1132.     pred = aktd;
  1133.   }
  1134.  
  1135.   if (((fird < 0.0) && (aktd > 0.0)) || ((fird > 0.0) && (aktd < 0.0)))
  1136.   {
  1137.     d.x = firP.x - aktP.x;
  1138.     d.y = firP.y - aktP.y;
  1139.     d.z = firP.z - aktP.z;
  1140.  
  1141.     k = -aktd / (VY2->x * d.x + VY2->y * d.y + VY2->z * d.z);
  1142.  
  1143.     intP.x = aktP.x + k * d.x;
  1144.     intP.y = aktP.y + k * d.y;
  1145.     intP.z = aktP.z + k * d.z;
  1146.  
  1147.     ClipPoints[pc++] = intP;
  1148.   }
  1149.  
  1150.   for (i = 0; i < pc; i++)
  1151.     Points[i] = ClipPoints[i];
  1152.  
  1153.   *PointCnt = pc;
  1154. }
  1155.  
  1156.  
  1157.  
  1158. /*****************************************************************************
  1159. *
  1160. * FUNCTION      : MInvers
  1161. *
  1162. * ARGUMENTS     : m - matrix to invert
  1163. *                 r - inverted matrix
  1164. *
  1165. * MODIFIED ARGS : r
  1166. *
  1167. * RETURN VALUE  : none
  1168. *
  1169. * AUTHOR        : Dieter Bayer, May, 1994
  1170. *
  1171. * DESCRIPTION
  1172. *
  1173. *   Invert a 4x4 matrix.
  1174. *
  1175. * CHANGES
  1176. *
  1177. *   -
  1178. *
  1179. ******************************************************************************/
  1180.  
  1181. void MInvers(r, m)
  1182. MATRIX *r, *m;
  1183. {
  1184.   DBL d00, d01, d02, d03;
  1185.   DBL d10, d11, d12, d13;
  1186.   DBL d20, d21, d22, d23;
  1187.   DBL d30, d31, d32, d33;
  1188.   DBL m00, m01, m02, m03;
  1189.   DBL m10, m11, m12, m13;
  1190.   DBL m20, m21, m22, m23;
  1191.   DBL m30, m31, m32, m33;
  1192.   DBL D;
  1193.  
  1194.   m00 = (*m)[0][0];  m01 = (*m)[0][1];  m02 = (*m)[0][2];  m03 = (*m)[0][3];
  1195.   m10 = (*m)[1][0];  m11 = (*m)[1][1];  m12 = (*m)[1][2];  m13 = (*m)[1][3];
  1196.   m20 = (*m)[2][0];  m21 = (*m)[2][1];  m22 = (*m)[2][2];  m23 = (*m)[2][3];
  1197.   m30 = (*m)[3][0];  m31 = (*m)[3][1];  m32 = (*m)[3][2];  m33 = (*m)[3][3];
  1198.  
  1199.   d00 = m11*m22*m33 + m12*m23*m31 + m13*m21*m32 - m31*m22*m13 - m32*m23*m11 - m33*m21*m12;
  1200.   d01 = m10*m22*m33 + m12*m23*m30 + m13*m20*m32 - m30*m22*m13 - m32*m23*m10 - m33*m20*m12;
  1201.   d02 = m10*m21*m33 + m11*m23*m30 + m13*m20*m31 - m30*m21*m13 - m31*m23*m10 - m33*m20*m11;
  1202.   d03 = m10*m21*m32 + m11*m22*m30 + m12*m20*m31 - m30*m21*m12 - m31*m22*m10 - m32*m20*m11;
  1203.  
  1204.   d10 = m01*m22*m33 + m02*m23*m31 + m03*m21*m32 - m31*m22*m03 - m32*m23*m01 - m33*m21*m02;
  1205.   d11 = m00*m22*m33 + m02*m23*m30 + m03*m20*m32 - m30*m22*m03 - m32*m23*m00 - m33*m20*m02;
  1206.   d12 = m00*m21*m33 + m01*m23*m30 + m03*m20*m31 - m30*m21*m03 - m31*m23*m00 - m33*m20*m01;
  1207.   d13 = m00*m21*m32 + m01*m22*m30 + m02*m20*m31 - m30*m21*m02 - m31*m22*m00 - m32*m20*m01;
  1208.  
  1209.   d20 = m01*m12*m33 + m02*m13*m31 + m03*m11*m32 - m31*m12*m03 - m32*m13*m01 - m33*m11*m02;
  1210.   d21 = m00*m12*m33 + m02*m13*m30 + m03*m10*m32 - m30*m12*m03 - m32*m13*m00 - m33*m10*m02;
  1211.   d22 = m00*m11*m33 + m01*m13*m30 + m03*m10*m31 - m30*m11*m03 - m31*m13*m00 - m33*m10*m01;
  1212.   d23 = m00*m11*m32 + m01*m12*m30 + m02*m10*m31 - m30*m11*m02 - m31*m12*m00 - m32*m10*m01;
  1213.  
  1214.   d30 = m01*m12*m23 + m02*m13*m21 + m03*m11*m22 - m21*m12*m03 - m22*m13*m01 - m23*m11*m02;
  1215.   d31 = m00*m12*m23 + m02*m13*m20 + m03*m10*m22 - m20*m12*m03 - m22*m13*m00 - m23*m10*m02;
  1216.   d32 = m00*m11*m23 + m01*m13*m20 + m03*m10*m21 - m20*m11*m03 - m21*m13*m00 - m23*m10*m01;
  1217.   d33 = m00*m11*m22 + m01*m12*m20 + m02*m10*m21 - m20*m11*m02 - m21*m12*m00 - m22*m10*m01;
  1218.  
  1219.   D = m00*d00 - m01*d01 + m02*d02 - m03*d03;
  1220.  
  1221.   if (fabs(D) < EPSILON)
  1222.     Fatal_Error("Singular matrix in MInvers.\n");
  1223.  
  1224.   (*r)[0][0] = +d00/D; (*r)[0][1] = -d10/D;  (*r)[0][2] = +d20/D; (*r)[0][3] = -d30/D;
  1225.   (*r)[1][0] = -d01/D; (*r)[1][1] = +d11/D;  (*r)[1][2] = -d21/D; (*r)[1][3] = +d31/D;
  1226.   (*r)[2][0] = +d02/D; (*r)[2][1] = -d12/D;  (*r)[2][2] = +d22/D; (*r)[2][3] = -d32/D;
  1227.   (*r)[3][0] = -d03/D; (*r)[3][1] = +d13/D;  (*r)[3][2] = -d23/D; (*r)[3][3] = +d33/D;
  1228. }
  1229.  
  1230.  
  1231.  
  1232. /*****************************************************************************
  1233. *
  1234. * FUNCTION      : Fatal_Error
  1235. *
  1236. * ARGUMENTS     : str - String to print to stderr
  1237. *
  1238. * MODIFIED ARGS : none
  1239. *
  1240. * RETURN VALUE  : none
  1241. *
  1242. * AUTHOR        : Dieter Bayer, May, 1994
  1243. *
  1244. * DESCRIPTION
  1245. *
  1246. *   Print an error message and leave program.
  1247. *
  1248. * CHANGES
  1249. *
  1250. *   -
  1251. *
  1252. ******************************************************************************/
  1253.  
  1254. void Fatal_Error(str)
  1255. char *str;
  1256. {
  1257.   fputs(str, stderr);
  1258.   exit(1);
  1259. }
  1260.  
  1261.  
  1262.  
  1263. /*****************************************************************************
  1264. *
  1265. * FUNCTION      : Fatal_MAError
  1266. *
  1267. * ARGUMENTS     : str - String to print to stderr after out of memory message
  1268. *
  1269. * MODIFIED ARGS : none
  1270. *
  1271. * RETURN VALUE  : none
  1272. *
  1273. * AUTHOR        : Dieter Bayer, May, 1994
  1274. *
  1275. * DESCRIPTION
  1276. *
  1277. *   Print an error message and leave program. Call if memory
  1278. *   allocation fails.
  1279. *
  1280. * CHANGES
  1281. *
  1282. *   -
  1283. *
  1284. ******************************************************************************/
  1285.  
  1286. void Fatal_MAError(str)
  1287. char *str;
  1288. {
  1289.   fprintf(stderr, "Out of memory. Cannot allocate %s.\n", str);
  1290.   exit (1);
  1291. }
  1292.  
  1293.  
  1294.  
  1295. /*****************************************************************************
  1296. *
  1297. * FUNCTION      : Begin_Point
  1298. *
  1299. * ARGUMENTS     : none
  1300. *
  1301. * MODIFIED ARGS : none
  1302. *
  1303. * RETURN VALUE  : none
  1304. *
  1305. * AUTHOR        : Dieter Bayer, May, 1994
  1306. *
  1307. * DESCRIPTION
  1308. *
  1309. *   Print points to stderr and initialize point counter.
  1310. *
  1311. * CHANGES
  1312. *
  1313. *   -
  1314. *
  1315. ******************************************************************************/
  1316.  
  1317. void Begin_Point()
  1318. {
  1319.   fprintf(stderr, "...");
  1320.   Point_Counter = 0;
  1321. }
  1322.  
  1323.  
  1324.  
  1325. /*****************************************************************************
  1326. *
  1327. * FUNCTION      : Print_Point
  1328. *
  1329. * ARGUMENTS     : Repeat - Determines after how many calls a point will be printed
  1330. *
  1331. * MODIFIED ARGS : none
  1332. *
  1333. * RETURN VALUE  : none
  1334. *
  1335. * AUTHOR        : Dieter Bayer, May, 1994
  1336. *
  1337. * DESCRIPTION
  1338. *
  1339. *   Print points to stderr.
  1340. *
  1341. * CHANGES
  1342. *
  1343. *   -
  1344. *
  1345. ******************************************************************************/
  1346.  
  1347. void Print_Point(Repeat)
  1348. int Repeat;
  1349. {
  1350.   if ((Point_Counter % Repeat) == 0)
  1351.     fprintf(stderr, ".");
  1352.   Point_Counter++;
  1353. }
  1354.  
  1355.  
  1356.  
  1357. /*****************************************************************************
  1358. *
  1359. * FUNCTION      : End_Point
  1360. *
  1361. * ARGUMENTS     : none
  1362. *
  1363. * MODIFIED ARGS : none
  1364. *
  1365. * RETURN VALUE  : none
  1366. *
  1367. * AUTHOR        : Dieter Bayer, May, 1994
  1368. *
  1369. * DESCRIPTION
  1370. *
  1371. *   Print newline to stderr.
  1372. *
  1373. * CHANGES
  1374. *
  1375. *   -
  1376. *
  1377. ******************************************************************************/
  1378.  
  1379. void End_Point()
  1380. {
  1381.   fprintf(stderr, "\n");
  1382. }
  1383.  
  1384.  
  1385.  
  1386. /*****************************************************************************
  1387. *
  1388. * FUNCTION      : Draw_Projection
  1389. *
  1390. * ARGUMENTS     : Project - projection to draw
  1391. *                 color   - Color to be used
  1392. *
  1393. * MODIFIED ARGS : none
  1394. *
  1395. * RETURN VALUE  : none
  1396. *
  1397. * AUTHOR        : Dieter Bayer, May, 1994
  1398. *
  1399. * DESCRIPTION
  1400. *
  1401. *   Draws a projection in the specified color.
  1402. *
  1403. * CHANGES
  1404. *
  1405. *   -
  1406. *
  1407. ******************************************************************************/
  1408.  
  1409. static void Draw_Projection(Project, color)
  1410. PROJECT *Project;
  1411. int color;
  1412. {
  1413.   int x, y, x1, x2, y1, y2;
  1414.   unsigned short int r, g, b;
  1415.  
  1416.   switch (color)
  1417.   {
  1418.     case RED   : r = 255; g = b = 0; break;
  1419.     case GREEN : g = 255; r = b = 0; break;
  1420.     case BLUE  : b = 255; r = g = 0; break;
  1421.     default    : r = g = b = 255;
  1422.   }
  1423.  
  1424.   x1 = Project->x1;
  1425.   x2 = Project->x2;
  1426.   y1 = Project->y1;
  1427.   y2 = Project->y2;
  1428.  
  1429.   if ((x1 <= x2) && (y1 <= y2))
  1430.   {
  1431.     if (x1 < 0) x1 = 0;
  1432.     if (x2 < 0) x2 = 0;
  1433.     if (y1 < 0) y1 = 0;
  1434.     if (y2 < 0) y2 = 0;
  1435.  
  1436.     if (x1 >= Frame.Screen_Width)  x1 = Frame.Screen_Width - 1;
  1437.     if (x2 >= Frame.Screen_Width)  x2 = Frame.Screen_Width - 1;
  1438.     if (y1 >= Frame.Screen_Height) y1 = Frame.Screen_Height - 1;
  1439.     if (y2 >= Frame.Screen_Height) y2 = Frame.Screen_Height - 1;
  1440.  
  1441.     for (x = x1; x <= x2; x++)
  1442.     {
  1443.       display_plot (x, y1, r, g, b);
  1444.       display_plot (x, y2, r, g, b);
  1445.     }
  1446.     for (y = y1; y <= y2; y++)
  1447.     {
  1448.       display_plot (x1, y, r, g, b);
  1449.       display_plot (x2, y, r, g, b);
  1450.     }
  1451.   }
  1452. }
  1453.  
  1454.  
  1455.  
  1456. /*****************************************************************************
  1457. *
  1458. * FUNCTION      : Draw_Vista
  1459. *
  1460. * ARGUMENTS     : Tree - current node/leaf in the vista tree
  1461. *
  1462. * MODIFIED ARGS : none
  1463. *
  1464. * RETURN VALUE  : none
  1465. *
  1466. * AUTHOR        : Dieter Bayer, May, 1994
  1467. *
  1468. * DESCRIPTION
  1469. *
  1470. *   Draws recursively all projections of subnodes in the current node.
  1471. *
  1472. * CHANGES
  1473. *
  1474. *   -
  1475. *
  1476. ******************************************************************************/
  1477.  
  1478. static void Draw_Vista(Tree)
  1479. PROJECT_TREE_NODE *Tree;
  1480. {
  1481.   unsigned short i;
  1482.   PROJECT_TREE_LEAF *Leaf;
  1483.  
  1484.   if (Tree->is_leaf)
  1485.   {
  1486.     Leaf = (PROJECT_TREE_LEAF *)Tree;
  1487.  
  1488.     if (Leaf->Object->Type & COMPOUND_OBJECT)
  1489.     {
  1490.       Draw_Projection(&Leaf->Project, BLUE);
  1491.     }
  1492.     else
  1493.     {
  1494.       Draw_Projection(&Leaf->Project, RED);
  1495.     }
  1496.   }
  1497.   else
  1498.   {
  1499.     for (i = 0; i < Tree->Entries; i++)
  1500.     {
  1501.       Draw_Vista(Tree->Entry[i]);
  1502.     }
  1503.   }
  1504.  
  1505.   /* draw bounding object's vista */
  1506.  
  1507. /*
  1508.   Draw_Projection(&Tree->Project, GREEN);
  1509. */
  1510. }
  1511.  
  1512.  
  1513.  
  1514. /*****************************************************************************
  1515. *
  1516. * FUNCTION      : Draw_Vista_Tree
  1517. *
  1518. * ARGUMENTS     : none
  1519. *
  1520. * MODIFIED ARGS : none
  1521. *
  1522. * RETURN VALUE  : none
  1523. *
  1524. * AUTHOR        : Dieter Bayer, May, 1994
  1525. *
  1526. * DESCRIPTION
  1527. *
  1528. *   Draw the vista tree.
  1529. *
  1530. * CHANGES
  1531. *
  1532. *   -
  1533. *
  1534. ******************************************************************************/
  1535.  
  1536. void Draw_Vista_Tree()
  1537. {
  1538.   if (Extended_Options & USE_VISTA_BUFFER)
  1539.   {
  1540.     Draw_Vista(Root_Vista);
  1541.   }
  1542. }
  1543.  
  1544.  
  1545.  
  1546. #endif
  1547.  
  1548.